package py.com.alfa.escriba.gui.controller;

import java.io.Serializable;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.WebApplicationContext;
import org.thymeleaf.TemplateEngine;
import org.winter.utils.command.ControllerObject;

import py.com.alfa.escriba.gui.controller.view.View;
import py.com.alfa.escriba.gui.exception.ExceptionHandler;
import py.com.alfa.escriba.gui.session.AuthenticationInfo;
import py.com.alfa.escriba.gui.session.SystemInfo;
import py.com.alfa.escriba.gui.spring.processors.SpringBean;
import py.com.alfa.escriba.gui.utils.ObjectUtils;


@Controller
@Scope("session")
@RequestMapping("/credenciales")
@SessionAttributes({AttributesNames.AUTHENTICATION_INFO})
public class ChangeCredentialController implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5712915702462858767L;

	private Logger log = LoggerFactory.getLogger(getClass());
	

	@SpringBean private SystemInfo systemInfo;

	@ControllerObject
	private AuthenticationInfo authInfo;

	@Autowired
	private WebApplicationContext wac;
	@Autowired
	private TemplateEngine templateEngine;
	
	private Locale locale;

	public ChangeCredentialController() {
		loadObjects();
	}

	private void loadObjects() {
		if ( this.getAuthInfo() == null ) {
			this.authInfo = new AuthenticationInfo();
		}
		setLocale(LocaleContextHolder.getLocale());
	}


	private String verifAuto() {
		Subject subject = SecurityUtils.getSubject();
		if (subject == null || !subject.isAuthenticated()) {
			return "redirect:/";
		}		
		return null;
	}
	
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String homePage(Model model) {
		loadObjects();
		String auto = this.verifAuto();
		if ( auto != null ) {
			return auto;
		}
		this.getAuthInfo().setUsername(systemInfo.getUserName());
		return View.CAMBIAR_CREDENCIAL;
	}

	@RequestMapping(value = "/cambiar", method = RequestMethod.POST)
	public String cambiar(Model model, HttpServletRequest request, HttpServletResponse response,
			   @ModelAttribute(AttributesNames.AUTHENTICATION_INFO) AuthenticationInfo authInfo, BindingResult result) {
		this.log.info("CREDENCIAL - cambiar!");
		try {
		    if ( authInfo.getPassword().equals(authInfo.getNewPassword())) {
		    	return "redirect:/credenciales/"+"La Contrase�a actual y la Contrase�a nueva no deben ser iguales";
		    }
		    
			if ( !ObjectUtils.validatePwd(authInfo.getNewPassword())) {
				return "redirect:/credenciales/"+"La Contrase�a no cumple con los requisitos";
			}			
		    if ( !authInfo.getConfPassword().equals(authInfo.getNewPassword())) {
		    	return "redirect:/credenciales/"+"La nueva Contrase�a y la confirmacion de la Contrase�a deben ser iguales";
		    }
		    return "redirect:/";
		} catch (Exception e) {
			this.log.error(e.getMessage(), e);
			String message = ExceptionHandler.handle(e, getLocale(), getClass());
		    return "redirect:/credenciales/"+message;			
		}
	}	

	
	  @RequestMapping(value = "/{message}", method = RequestMethod.GET)
	  public String cambiarPage(Model model, HttpServletRequest request, HttpServletResponse response, @PathVariable("message") String message) {
		  this.log.info("\n==============\nLogin with message: {}\n==============\n", message);
		    if(!ObjectUtils.isEmpty(message)){
		      systemInfo.setSystemError(true);
		      systemInfo.setErrorMessage(message);
		    }
	    model.addAttribute(AttributesNames.AUTHENTICATION_INFO, getAuthInfo());
	    return "/admin/cambiarCredencial";
	  }	

	/**
	 * @return the authInfo
	 */

	@ModelAttribute(AttributesNames.AUTHENTICATION_INFO)
	public AuthenticationInfo getAuthInfo() {
		return authInfo;
	}

	/**
	 * @param authInfo
	 *            the authInfo to set
	 */
	public void setAuthInfo(AuthenticationInfo authInfo) {
		this.authInfo = authInfo;
	}

	public Locale getLocale() {
		return locale;
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
	}
}
